// 玩家直升机类：实现玩家控制的直升机，包括救援功能和目标锁定显示
class Player extends Chopper {

    // 构造函数：初始化玩家直升机
    constructor() {
        super();
        // 添加到玩家分类桶
        this.buckets.push('player');

        // 救援相关属性
        this.ladderLength = 0;         // 救援梯子长度
        this.hangingPrisoner = null;   // 正在救援的囚犯
        this.rescuedPrisoners = 0;     // 已救援的囚犯数量

        // 受损警告音效相关
        this.lastDamageBeep = 0;       // 上次警告音效时间
    }

    // 销毁时停止引擎音效
    destroy() {
        if (this.sound) {
            this.sound.stop();
            this.sound = null;
        }
    }

    // 更新玩家直升机状态
    // @param elapsed: 经过的时间
    cycle(elapsed) {
        const { lockedTargetFactor } = this;

        // 初始化引擎音效
        if (!this.sound && this.age > 0.5) {
            this.sound = new FunZZfx(zzfxG(...[,,317,,20,0,,3.2,-12,16,,,.07,.1,,,,.59,.18,.12])); // Shoot 71
            this.sound.source.loop = true;
            this.sound.start();
        }

        super.cycle(elapsed);

        const { controls } = this;

        // 处理键盘控制
        controls.left = (DOWN[37] || DOWN[65] || DOWN[81]);   // 左箭头、A、Q
        controls.right = (DOWN[39] || DOWN[68]);              // 右箭头、D
        controls.up = (DOWN[38] || DOWN[87] || DOWN[90]);     // 上箭头、W、Z
        controls.down = (DOWN[40] || DOWN[83]);               // 下箭头、S
        controls.shoot = DOWN[32];                            // 空格键

        // 处理触摸控制（将屏幕分为四个区域）
        for (const touch of TOUCHES) {
            const relX = touch.x / CANVAS_WIDTH;

            controls.left = controls.left || isBetween(0, relX, 0.25);      // 左1/4屏幕
            controls.right = controls.right || isBetween(0.25, relX, 0.5);  // 左中1/4屏幕
            controls.shoot = controls.shoot || isBetween(0.5, relX, 0.75);  // 右中1/4屏幕
            controls.up = controls.up || isBetween(0.75, relX, 1);          // 右1/4屏幕
        }

        // 检测附近的囚犯
        let hasPrisoner;
        for (const prisoner of this.world.bucket('prisoner')) {
            if (dist(prisoner, this) < 150) {
                hasPrisoner = prisoner;
            }
        }

        // 根据是否有囚犯调整救援梯子长度
        const targetLadderLength = hasPrisoner && !this.hangingPrisoner ? 100 : 0;

        // 放下梯子时播放音效
        if (targetLadderLength && !this.ladderLength) {
            sound(...[,,100,.01,.08,.14,1,.8,10,,,,,,,,,.55,.02]); // Jump 405
        }

        // 平滑调整梯子长度
        this.ladderLength += between(
            -elapsed * 100,
            targetLadderLength - this.ladderLength,
            elapsed * 100,
        );

        // 根据螺旋桨动力调整引擎音效
        if (this.sound) {
            this.sound.setVolume(interpolate(0.5, 1, this.propellerPower));
            this.sound.setRate(interpolate(0.5, 1, this.propellerPower));
        }

        // 受损时播放警告音效
        if (this.age < this.damagedEnd && this.age - this.lastDamageBeep > 0.25) {
            this.lastDamageBeep = this.age;
            sound(...[.4,,434,,.03,.01,3,2,,5,,,,,168,,,.76,.03,,520]); // Blip 639
        }

        // 开始锁定目标时播放音效
        if (lockedTargetFactor === 0 && this.lockedTargetFactor > 0) {
            sound(...[,,354,.02,.28,.32,,.9,5,160,491,.07,.09,,,,,.66,.17,.39]); // Powerup 616
        }

        // 目标锁定完成时播放音效
        if (lockedTargetFactor < 1 && this.lockedTargetFactor >= 1) {
            sound(...[2,,12,.01,.04,.006,,2.8,,,-436,.01,.02,,,,.14,.61,.02]); // Blip 591
        }
    }

    // 渲染玩家直升机
    // @param camera: 当前相机实体
    render(camera) {
        // 渲染目标锁定指示器
        ctx.wrap(() => {
            if (!this.lockedTarget) return;

            // 锁定完成时闪烁效果
            if (this.lockedTargetFactor >= 1 && this.lockedTargetTime < 1 && (this.lockedTargetTime / 0.2 % 1) < 0.5) {
                return;
            }

            // 设置指示器样式（锁定完成为红色，锁定中为黄色）
            ctx.strokeStyle = ctx.fillStyle = this.lockedTargetFactor >= 1 ? '#f00' : '#ff0';
            ctx.globalAlpha = interpolate(0, 0.2, this.lockedTargetFactor);

            // 绘制锁定线
            ctx.beginPath();
            ctx.lineWidth = interpolate(40, 4, this.lockedTargetFactor);
            ctx.moveTo(this.x, this.y);
            ctx.lineTo(this.lockedTarget.x, this.lockedTarget.y);
            ctx.stroke();

            // 绘制目标框
            ctx.translate(this.lockedTarget.x, this.lockedTarget.y);

            ctx.globalAlpha = this.lockedTargetFactor;
            ctx.shadowColor = '#000';
            ctx.shadowOffsetY = 2;

            // 缩放动画
            const s = interpolate(2, 1, this.lockedTargetFactor);
            ctx.scale(s, s);

            // 旋转动画
            ctx.rotate(this.age * PI);

            // 绘制圆形框
            const radius = max(this.lockedTarget.radius, 20);
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.arc(0, 0, radius, 0, 2 * PI);
            ctx.stroke();

            // 绘制十字准星
            for (let i = 0 ; i < 4 ; i++) {
                ctx.rotate(PI / 2);
                ctx.fillRect(radius - 5, 0, 10, 2);
            }
        });

        // 渲染救援梯子
        ctx.wrap(() => {
            ctx.translate(this.x, this.y);
            ctx.fillStyle = '#000';
            // 绘制梯子两边
            ctx.fillRect(-5, 0, 2, this.ladderLength);
            ctx.fillRect(5, 0, -2, this.ladderLength);

            // 绘制梯子横档
            for (let y = this.ladderLength ; y >= 0 ; y -= 10) {
                ctx.fillRect(-5, y, 10, 2);
            }
        });

        // 调用父类渲染方法
        super.render(camera);
    }
}
